import struct
import socket
import numpy as np
from cv2 import cv2

bufsize = 1024

soc = None
# host = "127.0.0.1"
host = "192.168.0.189"
port = 8080
img = None
# 给视窗命名为 main
cv2.namedWindow("main")

def run():
    global soc, img
    # 1. 接收第一帧图片
    # 获取 socket 连接对象
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.connect((host, port))
    # 接受发送过来的数据: 数据长度
    lenb = soc.recv(4)
    # 将获取到的数据解包
    le = struct.unpack(">I", lenb)[0]
    # 初始化为 bytes 数据
    imb = b''
    # 将大于 bufsize 的部分作为一部分接收了
    while le > bufsize:
        t = soc.recv(bufsize)
        imb += t
        le -= len(t)
    # 将没超过bufsize的部分接收了
    while le > 0:
        t = soc.recv(le)
        imb += t
        le -= len(t)
    # 将缓存流数据转换为 数组
    data = np.frombuffer(imb, dtype=np.uint8)
    # 从指定内存中读取数据，将数据转换成图像格式，从网络中数据传输中恢复出图像
    # 第一张图
    img = cv2.imdecode(data, cv2.IMREAD_COLOR)

    # 2. 开始处理后面的差异化图像
    while True:
        # imshow() 用于在窗口显示图片
        # main 窗口名  图像名
        # cv2.cvtColor() 图像色彩转换 将BGR 图像转换为 RGB 图像
        # 因为 opencv 是以 BGR 的模式加载图像的，所以需要转换回 RGB 模式
        cv2.imshow("main", cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        # 获取差异图数据长度
        lenb = soc.recv(4)
        # 接收差异图数据， 并解析数据
        le = struct.unpack(">I", lenb)[0]
        # 初始化为 bypes 数据
        imb = b''
        # 接收处理数据
        while le > bufsize:
            t = soc.recv(bufsize)
            imb += t
            le -= len(t)
        while le > 0:
            t = soc.recv(le)
            imb += t
            le -= len(t)
        # 将缓存流数据转换为 数组
        data = np.frombuffer(imb, dtype=np.uint8)
        # 将内存缓存中读取的数据转换成 图像数据
        ims = cv2.imdecode(data, cv2.IMREAD_COLOR)
        # 将变化的数据加上
        img = img + ims
        # 刷新率
        cv2.waitKey(1)


run()